import ctypes
import threading

import ctypes
import os
from time import sleep

import pythoncom
from comtypes import CoInitialize
from comtypes.client import CreateObject
from win32com.client import Dispatch
from common.base import *

class Dm:
    def __init__(self):
        self.dm = None
        self.dms = []
        # 存放100个大漠对象
        self.dm_user = "xf30557fc317f617eead33dfc8de3bdd4ab9043"
        self.dm_pass = "xuuux6nyk8qw7zc6m7"
        try:
            self.dm = Dispatch('dm.dmsoft')
        except:
            log.info('本机并未安装大漠,正在免注册调用')
            # 重写路径，使用相对路径
            base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
            dms = ctypes.windll.LoadLibrary(os.path.join(base_dir, 'config', 'DmReg.dll'))
            location_dmreg = os.path.join(base_dir, 'config', 'dm.dll')
            CoInitialize()
            dms.SetDllPathW(location_dmreg, 0)
            self.dm = CreateObject('dm.dmsoft')
            log.info(f'免注册调用成功版本号为:{ self.dm.Ver()}')
        self.reg(dm_user=self.dm_user, dm_pass=self.dm_pass)

    def reg(self, dm_user, dm_pass):
        res = self.dm.Reg(dm_user, dm_pass)
        dm_res = {
            -1: "大漠无法连接网络",
            -2: "进程没有以管理员方式运行",
            0: "失败(未知错误)",
            1: "成功",
            2: "余额不足",
            3: "绑定了本机器,但是账户余额不足50元",
            4: "注册码错误",
            5: "你的机器或者IP在黑名单列表中或者不在白名单列表中",
            6: "非法使用插件。一般出现在定制插件时,使用了和绑定的用户名不同的注册码.也有可能是系统的语言设置不是中文简体,也可能有这个错误",
            7: "你的帐号因为非法使用被封禁。(如果是在虚拟机中使用插件,办必须使用Reg或者RegEx,不能使用RegNoMac或者RegExNoMac,否则可能会造成封号,或者封禁机器)",
            8: "ver_info不在你设置的附加白名单中",
            77: "机器码或者IP因为非法使用,而被封禁.(如果是在虚拟机中使用插件,必须使用Reg或者RegEx,不能使用RegNoMac或者RegExNoMac,否则可能会造成封号,或者封禁机器"
        }
        if res == 1:
            log.info("大漠注册成功")
            return self.dm
        else:
            log.info(res)
            log.info("大漠注册失败:" + dm_res.get(res))
        raise "dm.reg error"

    def bind_window(self, hwnd, display, mouse, keypad, mode):
        """
        绑定窗口到插件
        :param hwnd: 窗口句柄
        :param display: 显示模式
        :param mouse: 鼠标模式
        :param keypad: 键盘模式
        :param mode: 绑定模式
        :return: 绑定结果
        """
        if hasattr(self.dm, 'BindWindow'):
            result = self.dm.BindWindow(hwnd, display, mouse, keypad, mode)
            if result == 1:
                log.info("窗口绑定成功")
            else:
                log.info("窗口绑定失败")
            return result
        else:
            log.info("dm.dll 中未找到 BindWindow 函数")
            return -1

    def unbind_window(self):
        self.dm.UnBindWindow()

    def keyboard_input(self, text):
        """
        模拟键盘输入
        :param text: 要输入的文本
        """
        if hasattr(self.dm, 'KeyPressStr'):
            self.dm.KeyPressStr(text, 1)
        else:
            log.info("dm.dll 中未找到 KeyPressStr 函数")

    def Capture(self, x1, y1, x2, y2, pic_name):
        base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        pic_path = os.path.join(base_dir, 'data', 'tmp', pic_name)
        if hasattr(self.dm, 'Capture'):
            self.dm.Capture(x1, y1, x2, y2, pic_path)
            return pic_path
        else:
            log.info("dm.dll 中未找到 Capture 函数")

    def Find_pic(self, x1, y1, x2, y2, pic_name, delta_color, sim, dir):
        """
        查找图片
        :param x1: 查找区域左上角 x 坐标
        :param y1: 查找区域左上角 y 坐标
        :param x2: 查找区域右下角 x 坐标
        :param y2: 查找区域右下角 y 坐标
        :param pic_name: 图片文件名
        :param delta_color: 颜色偏差
        :param sim: 相似度
        :param dir: 查找方向
        :return: 查找结果（x, y 坐标）
        """
        #self.dm.SetPath(base_dir+"/data/picture/")
        pic_path =os.path.join(base_dir, 'data', 'picture', pic_name)
        #print(pic_path)
        if hasattr(self.dm, 'FindPic'):
            result = self.dm.FindPic(x1, y1, x2, y2, pic_path, delta_color, sim, dir)
            #print(result)
            if result[2] == 0:
                log.info(f"找到图片，坐标: ({result[0]}, {result[1]})")
                return result[0], result[1]
            else:
                log.info("未找到图片")
                return -1, -1
        else:
            log.info("dm.dll 中未找到 FindPic 函数")
            return -1, -1

    def LeftClick(self, x, y, w, h):
        """
        模拟鼠标点击
        :param x: 点击位置的 x 坐标
        :param y: 点击位置的 y 坐标
        """
        if hasattr(self.dm, 'MoveToEx'):
            self.dm.MoveToEx(x, y,w,h)
            log.info(f"点击坐标{(x,y)}")
        else:
            log.info("dm.dll 中未找到 MoveTo")
        if hasattr(self.dm, 'LeftClick'):
            self.dm.LeftClick()
        else:
            log.info("dm.dll 中未找到  LeftClick 函数")

    def MoveToEx(self,x,y,w,h):
        """
        模拟鼠标移动
        :param x: 点击位置的 x 坐标
        :param y: 点击位置的 y 坐标
        """
        if hasattr(self.dm, 'MoveToEx'):
            self.dm.MoveToEx(x, y,w,h)
        else:
            log.info("dm.dll 中未找到 MoveToEx")

    def LeftDoubleClick(self,x,y):
        """
        模拟鼠标左键双击
        :param x: 点击位置的 x 坐标
        :param y: 点击位置的 y 坐标
        """
        if hasattr(self.dm, 'MoveTo'):
            self.dm.MoveTo(x, y)
        else:
            log.info("dm.dll 中未找到 MoveTo")
        if hasattr(self.dm, 'LeftClick'):
            self.dm.LeftDoubleClick()
        else:
            log.info("dm.dll 中未找到  LeftClick 函数")

    def WheelUp(self):
        ""
        if hasattr(self.dm, 'WheelUp'):
            self.dm.WheelUp()
            log.info("鼠标向上滚动")
        else:
            log.info("dm.dll 中未找到 WheelUp")

    def WheelDown(self):
        ""
        if hasattr(self.dm, 'WheelUp'):
            self.dm.WheelDown()
            log.info("鼠标向下滚动")
        else:
            log.info("dm.dll 中未找到 WheelDown")